
// 装饰器是修饰类的  可以修饰类中的属性和方法 ， 函数存在变量提升所以无法进行修饰

// 装饰器可以实现 同一个装饰器修饰不同的类  扩展

function addSay(target:{new (...args:any[]):any}){
    target.prototype.say = function(){
        console.log('say')
    }
}

function toUpperCase(flag:boolean){ // 为了方便可以传递参数
    return function(target:any,key:string){ // 装饰器函数
        let value = ''
        Object.defineProperty(target,key,{ // 给原型先定义属性
            get(){
                return flag? value.toUpperCase(): value.toLowerCase()
            },
            set(newValue:string){
                value = newValue
            }
        })
    }
}

function beforeDrink(str:string){
    return function(target:any,key:string,descripor:PropertyDescriptor){
        let oldValue = descripor.value;
        descripor.value = function(){
            console.log(str);
            oldValue.call(target);
        }
    }
}


// addSay(person)  @语法糖
@addSay
class Person {
    // say!:()=>void
    @toUpperCase(true)
    name:string = 'ZS'; // 实例上的还是原型上的 

    @beforeDrink('我渴了')
    drink(){
        console.log('喝水')
    }
}
// 可以扩展静态的属性和原型方法的参数 。。。
let person = new Person();
person.drink()


let namesss:(aa:number | boolean)=>string|number|boolean = function (aa:number|boolean|string):boolean{
    return false
}   
namesss(1) 

export {}